package com.parking.certified.controller;


import com.parking.certified.client.form.CertifiedSelectStallNumForm;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.parking.certified.dao.CertifiedAccountMapper;
import com.parking.certified.dao.CertifiedInfoMapper;
import com.parking.certified.dto.*;
import com.parking.certified.entity.CertifiedAccount;
import com.parking.certified.entity.CertifiedInfo;
import com.parking.certified.exception.CertifiedException;
import com.parking.certified.exception.CertifiedExceptionCode;
import com.parking.certified.form.*;
import com.parking.certified.service.CertifiedAccountService;
import com.parking.certified.service.CertifiedInfoService;
import com.parking.common.core.model.PageInfo;
import com.parking.common.core.model.Result;
import com.parking.common.core.model.StateData;
import com.parking.common.core.util.BeanUtilCommon;
import com.parking.common.core.util.JwtUtil;
import com.parking.common.web.aop.Permission;
import com.parking.common.web.util.FileUtil;
import com.parking.common.web.util.OssUtil;
import com.parking.common.web.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 彭于晏
 * @since 2023年11月29日
 */
@RestController
@RequestMapping("/certifiedInfo")
@Api(tags = "物业信息")
public class CertifiedInfoController {
    @Resource
    private CertifiedInfoService certifiedInfoService;
    @Resource
    private CertifiedInfoMapper certifiedInfoMapper;
    @Resource
    private CertifiedAccountMapper certifiedAccountMapper;
    @Resource
    private OssUtil ossUtil;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private CertifiedAccountService certifiedAccountService;
    /***
     * 物业自己修改信息
     * 参数:
     * (物业名称):certifiedInfoName
     * (物业联系方式):certifiedInfoTel
     * @param form
     * @param authorization
     * @return
     * @throws Exception
     */
    @PostMapping("/updateCertifiedInfo.certified")
//    @Permission(resources = "/updateCertifiedInfo.certified")
    @ApiOperation("修改物业信息")
    public Result updateCertified(@RequestBody UpdateCertifiedForm form,@RequestHeader("authorization") String authorization)throws Exception{
        System.out.println(authorization+"参数11111111111111");
        Integer certifiedAccountId = JwtUtil.getCertifiedAccountId(authorization);
        certifiedInfoService.updateCertified(form,certifiedAccountId);
        return Result.getResult().setMessage("修改成功").setCode(200);
    }

    /***
     * 物业查询自己的信息
     * @param authorization
     * @return dto 物业的个人信息
     * @throws Exception
     */
    @GetMapping("/selectCertified.certified")
//    @Permission(resources = "/selectCertified.certified")
    @ApiOperation("物业查询自己的信息")
    public Result<CertifiedInfoDTO> selectCertifiedInfoAccount(@RequestHeader("authorization") String authorization)throws Exception{
//        String refreshToken = redisUtil.get(authorization);
        Integer certifiedAccountId = JwtUtil.getCertifiedAccountId(authorization);
        CertifiedInfoDTO dto = certifiedInfoService.selectCertifiedInfoAccount(certifiedAccountId);
        return Result.getResult(CertifiedInfoDTO.class).setMessage("查询成功").setCode(200).setData(dto);
    }

    /***
     * 平台查询物业
     * 参数:
     * (物业名称):certifiedInfoName
     * (物业电话):certifiedInfoTel
     * (页数):pageNum
     * (总条数):pageSize
     * @param form
     * @return
     */
    @PostMapping("/selectCertifiedInfo.platform")
    @Permission(resources = "/selectCertifiedInfo.platform")
    @ApiOperation("平台查询物业信息")
    public Result select(@RequestBody SelectCertifiedForm form,@RequestHeader("authorization") String authorization)throws Exception{
        Integer platformId = JwtUtil.getPlatformId(authorization);
        PageInfo pageInfo = certifiedInfoService.selectCertified(form,platformId);
        return Result.getResult().setMessage("查询成功").setCode(200).setData(pageInfo);
    }

    /**
     *selectInfo ：平台查询所有物业的名称,id
     *@return IdNameDTO 物业的名称,id
     */
    @PostMapping("/selectInfo.platform")
    @ApiOperation("平台查询所有物业的名称,id")
    public Result<Set<IdNameDTO>> selectInfo()throws Exception{
        List<CertifiedInfo> list = certifiedInfoService.list();
        HashSet<IdNameDTO> set = new HashSet<>();
        for (CertifiedInfo info : list) {
            set.add(BeanUtil.toBean(info,IdNameDTO.class));
        }
        return Result.getSetResult(IdNameDTO.class).setMessage("查询成功").setCode(200).setData(set);
    }


    /***
     * 用户查询物业
     * 参数:
     * (物业名称):certifiedInfoName
     * (物业电话):certifiedInfoTel
     * (页数):pageNum
     * (总条数):pageSize
     * @param form
     * @return
     */
    @PostMapping("/selectUser.user")
//    @Permission(resources = "/selectUser.user")
    @ApiOperation("用户查询物业")
    public Result selectUser(@RequestBody SelectCertifiedForm form,@RequestHeader("authorization") String authorization)throws Exception{
        Integer userId = JwtUtil.getUserId(authorization);
        CertifiedInfoDTO dto = certifiedInfoService.selectUser(form,userId);
        return Result.getResult().setMessage("查询成功").setCode(200).setData(dto);
    }

    /**
     * 车位模块的调用
     * @param certifiedAccountId:物业账号id
     * selectCertifiedInfo:物业信息查询
     * SelectCertifiedInfoDTO:物业信息查询返回对象
     * @return
     */
    @GetMapping("/selectCertifiedInfo/{certifiedAccountId}")
    @ApiOperation("物业信息查询(车位模块的调用)")
    public Result<SelectCertifiedInfoDTO> selectCertifiedInfo (@PathVariable("certifiedAccountId") Integer certifiedAccountId)throws Exception{

        if (certifiedAccountId==0){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_ID);
        }
        SelectCertifiedInfoDTO dto = certifiedInfoService.selectCertifiedInfo(certifiedAccountId);
        return Result.getResult().setMessage("查询成功").setCode(200).setData(dto);
    }

    /**
     * 根据ID查询物业信息
     * 参数: 物业信息Id   certifiedInfoId
     * 返回: 物业名称     certifiedInfoName
     *      物业电话     certifiedInfoTel
     *      物业地址     certifiedInfoAddress
     *      普通车位单价  stallUnitPrice
     *      充电车位单价  chargeUnitPrice
     * 方法: 1.判断certifiedInfoId是否存在对应的物业账号 若不存在则抛异常
     *      3.将物业账号放入Dto返回
     * */
    @GetMapping("/selectCertifiedInfoById")
    @ApiOperation("根据ID查询物业信息(订单模块调用)")
    Result<CertifiedInfoClientDto> selectCertifiedInfoById(@RequestParam("certifiedInfoId") Integer certifiedInfoId){
        CertifiedInfoClientDto dto = certifiedInfoService.selectCertifiedInfoById(certifiedInfoId);
        return Result.getResult().setMessage("查询成功").setCode(200).setData(dto);
    }
    /**
     * 查询所有状态正常的物业信息
     * 返回: 物业信息Id   certifiedInfoId
     *      物业名称     certifiedInfoName
     *      物业电话     certifiedInfoTel
     *      物业地址     certifiedInfoAddress
     *      普通车位单价  stallUnitPrice
     *      充电车位单价  chargeUnitPrice
     * 方法: 1.查询所有状态正常的物业信息
     *      3.放入Dto返回
     * */
    @GetMapping("/selectAllCertifiedInfo")
    @ApiOperation("查询所有状态正常的物业信息(订单模块调用)")
    Result<List<CertifiedInfoClientDto>> selectAllCertifiedInfo(){
        List<CertifiedAccount> accounts = certifiedAccountMapper.selectList(new QueryWrapper<CertifiedAccount>()
                .eq("certified_account_state", StateData.CERTIFIED_STATE_ENABLE));
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        wrapper.in("certified_account_id",accounts.stream().map(CertifiedAccount::getCertifiedAccountId).collect(Collectors.toList()));
        List<CertifiedInfo> infos = certifiedInfoMapper.selectList(wrapper);
        List<CertifiedInfoClientDto> dtos = BeanUtilCommon.BeanToList(infos, CertifiedInfoClientDto.class);
        return Result.getListResult(CertifiedInfoClientDto.class).setMessage("查询成功").setData(dtos);
    }
    /**
     * 更新物业评分
     * 返回: List<CertifiedScoreDto> 物业评分Dto集合
     *      CertifiedScoreDto 物业评分Dto
     *          certifiedInfoId    物业信息Id
     *          certifiedInfoScore 物业评分
     * 方法: 给所有certifiedInfoId的物业信息赋分certifiedInfoScore
     *      1.查询certifiedInfoId对应的物业信息
     *      2.在Java层面修改物业评分certifiedInfoScore
     *      3.批量修改 (CertifiedInfoService业务层方法 saveOrUpdateBatch)
     * */
    @PutMapping("/certifiedScoring")
    @ApiOperation("更新物业评分（订单模块调用）")
    Result certifiedScoring(@RequestBody CertifiedScoreForm form){
        certifiedInfoService.certifiedScoring(form);
        return Result.getResult().setMessage("更新成功").setCode(200);
    }
    /**
     * distanceCertifiedCall：获取距离范围内的所有物业信息
     * @param form 查询距离范围内的所有物业信息参数
     * @return Set<DistanceCertifiedInfoDto>:距离范围内的物业信息对象
     */
    @PostMapping("/distanceCertifiedCall")
    @ApiOperation("获取距离范围内的所有物业信息")
    public Result <Set<DistanceCertifiedInfoDto>> distanceCertifiedCall(@RequestBody SelectDistanceCertifiedInfoForm form)throws Exception{
//        Integer userId = JwtUtil.getUserId(authorization);
        Set<DistanceCertifiedInfoDto> dtos = certifiedInfoService.distanceCertifiedCall(form);
        return Result.getSetResult(DistanceCertifiedInfoDto.class).setMessage("调用成功").setData(dtos);
    }

    /**
     * certifiedInfoAndStateServerCall:查询物业信息及物业账号状态（车位模块调用）
//     * @param certifiedInfoId ：物业信息id
     * @return  SelectCertifiedInfoAndStateDTO： 物业信息及物业账号状态 对象
     */
    @GetMapping("/certifiedInfoAndStateServerCall")
    @ApiOperation("查询物业信息及物业账号状态（车位模块调用）")
    Result<SelectCertifiedInfoAndStateDTO> certifiedInfoAndStateServerCall(@RequestParam("certifiedInfoId")Integer certifiedInfoId) {
        if (certifiedInfoId==null) {
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_INFO_ID_IS_NULL);//物业信息id不存在
        }
        CertifiedInfo certifiedInfo = certifiedInfoService.getById(certifiedInfoId);
        CertifiedAccount certifiedAccount = certifiedAccountService.getOne(new QueryWrapper<CertifiedAccount>().eq("certified_info_id", certifiedInfoId));
        if (certifiedAccount==null) {
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_ACCOUNT_IS_NULL);//物业账号对象不存在
        }
        Integer certifiedAccountState = certifiedAccount.getCertifiedAccountState();
        SelectCertifiedInfoAndStateDTO dto = BeanUtil.toBean(certifiedInfo, SelectCertifiedInfoAndStateDTO.class);
        dto.setCertifiedAccountState(certifiedAccountState);
        return Result.getResult(SelectCertifiedInfoAndStateDTO.class).setMessage("查询成功").setData(dto);
    }
//    @GetMapping("/certifiedInfoAndStateServerCall")
//    Result<SelectCertifiedInfoAndStateDTO> certifiedInfoAndStateServerCall(@RequestParam("certifiedInfoId")Integer certifiedInfoId) {
//
//       return null;
//    }

    /***
     *根据车辆类型查询物业信息
     * @param form stallType 车位类型  certifiedInfoId 物业id
     * @return 物业信息的dto
     */
    @PostMapping("/distanceCertifiedStall")
    @ApiOperation("根据车辆类型查询物业信息")
    public Result distanceCertifiedStall(@RequestBody CertifiedSelectStallNumForm form)throws Exception{
        CertifiedInfoDTO infoDTO = certifiedInfoService.distanceCertifiedStall(form);
        return Result.getResult().setMessage("查询成功").setCode(200).setData(infoDTO);
    }

    /***
     * 上传物业营业执照
     * @param image
     * @return
     * @throws Exception
     */
    @ApiOperation("上传物业营业执照")
//    @Permission(resources = "/uploadCertifiedImg.certified")
    @PostMapping("/uploadCertifiedImg")
    public Result upLoad(MultipartFile image) throws Exception {
        InputStream stream = image.getInputStream();
        byte[] header=new byte[8];//解析字节码
        stream.read(header,0,8);//字节流读取文件
        if (!(FileUtil.isJpg(header)||FileUtil.isPng(header))){
            //真=》假=》真（抛异常）
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_DILE_NO);
        }
        //去掉uuid的横线
        String prefix = UUID.randomUUID().toString().replaceAll("-", "");
        //随机字符后缀文件格式
        String name = prefix + "." + (FileUtil.isJpg(header) ? "jpg" : "png");
        //调用上传oss的方法，获取oss的地址
        String path = ossUtil.uploadFile(image.getInputStream(), name);
        return Result.getResult().setMessage("上传营业执照成功").setCode(200).setData(path);
    }

    /***
     * 修改营业执照
     * @param image
     * @param authorization
     * @return
     * @throws Exception
     */
    @PostMapping("/updateCertifiedImg.certified")
    @ApiOperation("修改营业执照")
    public Result upUserInfoImg(MultipartFile image,@RequestHeader("authorization") String authorization) throws Exception {
        InputStream stream = image.getInputStream();
        byte[] header=new byte[8];//解析字节码
        stream.read(header,0,8);//字节流读取文件
        if (!(FileUtil.isJpg(header)||FileUtil.isPng(header))){
            //真=》假=》真（抛异常）
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_DILE_NO);
        }
        //去掉uuid的横线
        String prefix = UUID.randomUUID().toString().replaceAll("-", "");
        //随机字符后缀文件格式
        String name = prefix + "." + (FileUtil.isJpg(header) ? "jpg" : "png");
        UpdateCertifiedImgForm form = new UpdateCertifiedImgForm();
        form.setFileName(name);
        form.setImage(image);
        String refreshToken = redisUtil.get(authorization);
        Integer certifiedAccountId = JwtUtil.getCertifiedAccountId(refreshToken);
        form.setCertifiedInfoId(certifiedAccountId);
        certifiedInfoService.upCertifiedInfoImg(form);
        return Result.getResult().setMessage("修改营业执照成功").setCode(200);
    }

    /***
     *用户查询物业详细信息
     * @param form
     * @return
     * @throws Exception
     */
    @PostMapping("/selectCertifiedInfoForUser")
    @ApiOperation("用户根据经纬度查询附近范围物业详细信息")
    public Result<CertifiedInfoDTO> selectCertifiedInfoForUser(@RequestBody SelectCertifiedInfoForUserForm form)throws Exception{
        List<CertifiedInfoDTO> dtos = certifiedInfoService.selectCertifiedInfoForUser(form);
        System.out.println("检测参数："+dtos);
        return Result.getResult().setCode(200).setMessage("查询成功").setData(dtos);
    }



    /**
     * selectCertifiedInfoByIds:根据物业信息ids获取物业信息集合(车位模块调用)
     * @param certifiedInfoIds
     * @return
     */
    @ApiOperation("根据物业信息ids获取物业信息集合(车位模块调用)")
    @PostMapping("/selectCertifiedInfoByIds")
    Result<Set<CertifiedInfoByIdsDTO>> selectCertifiedInfoByIds(@RequestBody Set<Integer> certifiedInfoIds) {
        if (certifiedInfoIds==null) {
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IDS_IS_NULL);//物业信息ids不存在
        }
        List<CertifiedInfo> certifiedInfos = certifiedInfoService.listByIds(certifiedInfoIds);
        Set<CertifiedInfoByIdsDTO> dtos = new HashSet<>();
        if (certifiedInfos!=null) {
            for (CertifiedInfo certifiedInfo : certifiedInfos) {
                dtos.add(BeanUtil.toBean(certifiedInfo,CertifiedInfoByIdsDTO.class));
            }
        }
        return Result.getSetResult(CertifiedInfoByIdsDTO.class).setMessage("查询成功").setData(dtos);
    }
    @PostMapping("/updateStallPrice.certified")
    @ApiOperation("物业修改车位价格")
    public Result updateStallPrice(@RequestBody UpdateStallPriceForm form,@RequestHeader("authorization") String authorization)throws Exception{
        Integer certifiedAccountId = JwtUtil.getCertifiedAccountId(authorization);
        certifiedInfoService.updateStallPrice(form,certifiedAccountId);
        return Result.getResult().setMessage("修改成功").setCode(200);
    }

    @GetMapping("/findCertifiedInfoById")
    @ApiOperation("查询物业信息（出租客模块调用）")
    Result<CertifiedDto> findCertifiedInfoById(@RequestParam("certifiedInfoId") Integer certifiedInfoId) {
        System.out.println(certifiedInfoId+"接收参数");
        CertifiedDto dto=certifiedAccountService.findCertifiedInfoById(certifiedInfoId);
        System.out.println(dto+"返回参数");
        return Result.getResult(CertifiedDto.class).setMessage("查询成功").setData(dto);
    }
}

